'use strict';

const Service = require('egg').Service;

class DormService extends Service {
  // 批量新增宿舍
  async insertManyDorms(dorms) {
    const ctx = this.ctx;
    const checkRes = await this.checkDorms(dorms);
    if (checkRes.errcode) {
      return checkRes;
    }

    for (const dorm of dorms) {
      const buildingId = (await ctx.service.building.findBuildingByNumber(dorm.building_num))._id;
      const dorm_num = dorm.building_num + "#" + dorm.house_num;

      await ctx.model.Dorm.create({
        dorm_num,
        building_id: buildingId,
        contain_count: dorm.contain_count,
        reside_count: 0,
        dorm_status: 1
      });
    }

    return { errcode: 0 };
  }

  // 判断要插入的宿舍数组是否可用
  async checkDorms(dorms) {
    const { ctx } = this;
    const errorDorms = [];
    for (const dorm of dorms) {
      const errors = [];
      const dorm_num = dorm.building_num + "#" + dorm.house_num;
      const isExist = await this.findDormByNumber(dorm_num);
      if (isExist) {
        errors.push({
          errcode: 1,
          msg: "宿舍号已存在"
        });
      }
      const buildingExist = await ctx.service.building.findBuildingByNumber(dorm.building_num);
      if (!buildingExist) {
        errors.push({
          errcode: 2,
          msg: "楼栋号不存在"
        });
      }

      if (errors.length) {
        errorDorms.push({ dorm, errors });
      }
    }

    if (errorDorms.length) {
      return { errcode: 1, errorDorms };
    }

    return { errcode: 0 };
  }


  // 根据宿舍号查找宿舍
  async findDormByNumber(number) {
    const { ctx } = this;
    const res = await ctx.model.Dorm.findOne({
      dorm_num: number,
    }).populate('building_id');
    return res;
  }

  // 根据宿舍号查找宿舍ObjectId
  async fingObjectIdByNumber(number) {
    const res = await this.ctx.model.Dorm.findOne({
      dorm_num: number,
    });
    if (!res) {
      return null;
    }
    return res._id;
  }

  // 查询宿舍
  async searchDorms(conditions) {
    const ctx = this.ctx;
    const page = conditions.page || 1;
    const pageSize = conditions.pageSize || 10;
    const query = {};
    query.dorm_num = { $regex: new RegExp(conditions.keyword) };
    if (conditions.building_num) {
      query.building_id = (await ctx.service.building.findBuildingByNumber(conditions.building_num))._id;
    }

    const [list, total] = await Promise.all([
      ctx.model.Dorm.find(query)
        .populate('building_id', 'building_num  -_id')
        .sort('dorm_num')
        .skip((page - 1) * pageSize)
        .limit(pageSize),
      ctx.model.Dorm.find(query).count(),
    ]);

    const dormCounts = await this.getDormCount();
    list.forEach(dorm => {
      const count = dormCounts.find(item => dorm._id.equals(item._id));
      if (count) {
        dorm.reside_count = count.total;
      } else {
        dorm.reside_count = 0;
      }
    });

    return {
      list,
      paging: ctx.helper.getPaging(total, pageSize)
    };
  }

  // 获取宿舍人数统计信息
  async getDormCount() {
    const { ctx } = this;
    return await ctx.model.Student.aggregate().group({ _id: "$dorm_id", total: { $sum: 1 } });
  }

  // 根据宿舍号查询宿舍人数信息
  async checkDormStudentCount(dorm_num) {
    const { ctx } = this;
    if (!dorm_num) {
      return {
        errcode: -1,
        msg: "请输入宿舍号"
      };
    }
    const dorm = await this.findDormByNumber(dorm_num);
    if (!dorm) {
      return {
        errcode: 1,
        msg: "该宿舍不存在"
      };
    }
    const dorm_id = dorm._id;
    const count = await ctx.model.Student.find({ dorm_id }).count();
    const dormCount = {
      dorm_id,
      reside_count: count,
      contain_count: dorm.contain_count,
    };
    const isFull = count >= dorm.contain_count;
    if (isFull) {
      return {
        errcode: 2,
        msg: "该宿舍已满",
        data: dormCount
      };
    }
    return {
      errcode: 0,
      data: dormCount
    };
  }

  // 判断宿舍是否可以删除
  async beforeRemoveDorm(id) {
    const { ctx } = this;
    const errors = [];
    const isExist = await ctx.model.Dorm.findById(id);
    if (!isExist) {
      errors.push("该宿舍已不存在");
    }
    const count = await ctx.model.Student.find({ dorm_id: id }).count();
    if (count && isExist) {
      errors.push("该宿舍已分配学生");
    }
    if (errors.length) {
      return { errcode: 1, errors };
    }

    return { errcode: 0 };
  }

  // 删除一个宿舍
  async removeOneDorm(id) {
    const { ctx } = this;
    const checkRes = await this.beforeRemoveDorm(id);
    if (checkRes.errcode) {
      return checkRes;
    }
    await ctx.model.Dorm.deleteOne({ _id: id });
    return { errcode: 0 };
  }

  // 修改宿舍信息
  async updateDorm(data) {
    const { ctx } = this;
    const curDormExist = await ctx.model.Dorm.findById(data.id);
    if (!curDormExist) {
      return { errcode: -1, msg: "该宿舍已不存在" };
    }
    const dorm_num = data.building_num + "#" + data.house_num;
    const existDorm = await ctx.model.Dorm.findOne({ dorm_num });

    if (existDorm && !(existDorm._id.equals(data.id))) {
      return { errcode: 1, msg: "宿舍号已存在" };
    }
    const building_id = (await ctx.service.building.findBuildingByNumber(data.building_num))._id;
    await ctx.model.Dorm.findOneAndUpdate({ _id: data.id }, {
      dorm_num,
      building_id,
      contain_count: data.contain_count
    });

    return { errcode: 0 };

  }

}

module.exports = DormService;
